package standard;

import gui.scene.EntityLayer;
import gui.scene.Layer;
import gui.scene.LayeredScene;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.Queue;

import net.ByteBuffer;
import net.Connection;
import util.ResourceManager;
import core.Entity;
import core.GameKeyAction;
import core.GameState;
import core.InputManager;
import core.ViewableEntity;

public class MainGameState implements GameState {

	private LayeredScene scene;
	private final Connection server;

	private final GameKeyAction moveForward = new GameKeyAction("Move Forward");
	private final GameKeyAction moveBackward = new GameKeyAction(
			"Move Backward");
	private final GameKeyAction turnLeft = new GameKeyAction("Turn Left");
	private final GameKeyAction turnRight = new GameKeyAction("Turn Right");

	private final ByteBuffer buf = new ByteBuffer();

	public MainGameState(Connection server) {
		this.server = server;
	}

	private void init() {
		scene = new LayeredScene();
		EntityLayer entityLayer = new EntityLayer(new SimpleEntityRenderer());
		scene.addToFront(new Layer() {
			@Override
			public void render(Rectangle r, Graphics2D g) {
				g.setColor(Color.black);
				g.fillRect(r.x, r.y, r.width, r.height);
			}
		}, Common.BACKGROUND);
		scene.addToFront(entityLayer, Common.ENTITY_LAYER);
	}

	@Override
	public String getName() {
		return "MainGame";
	}

	@Override
	public String getNextState() {
		return null;
	}

	@Override
	public void handleNewEntity(Entity e) {
		if (e instanceof ViewableEntity)
			scene.addEntity((ViewableEntity) e);
	}

	@Override
	public void loadResources(ResourceManager arg0) {
		init();
	}

	@Override
	public void render(Graphics2D g, int screenWidth, int screenHeight) {
		scene.render(0, 0, screenWidth, screenHeight, g);
	}

	@Override
	public void start(InputManager inputManager) {
		inputManager.bind(KeyEvent.VK_UP, moveForward);
		inputManager.bind(KeyEvent.VK_DOWN, moveBackward);
		inputManager.bind(KeyEvent.VK_LEFT, turnLeft);
		inputManager.bind(KeyEvent.VK_RIGHT, turnRight);
	}

	@Override
	public void stop() {
		scene = null;
	}

	@Override
	public synchronized void update(int millis) {
		if (moveForward.isStateChanged()) {
			buf.add(Common.FORWARD);
			if (moveForward.isKeyDown())
				buf.add(1);
			else
				buf.add(0);
			server.sendUDP(buf.toByteArray());
			buf.reset();
		}
		if (moveBackward.isStateChanged()) {
			buf.add(Common.BACKWARD);
			if (moveBackward.isKeyDown())
				buf.add(1);
			else
				buf.add(0);
			server.sendUDP(buf.toByteArray());
			buf.reset();
		}
		if (turnLeft.isStateChanged()) {
			buf.add(Common.LEFT);
			if (turnLeft.isKeyDown())
				buf.add(1);
			else
				buf.add(0);
			server.sendUDP(buf.toByteArray());
			buf.reset();
		}
		if (turnRight.isStateChanged()) {
			buf.add(Common.RIGHT);
			if (turnRight.isKeyDown())
				buf.add(1);
			else
				buf.add(0);
			server.sendUDP(buf.toByteArray());
			buf.reset();
		}
	}

	@Override
	public void handle(Queue<MouseEvent> mouseEvents) {
		// Do Nothing
	}
}
